package eu.irreality.dai.gameplay.entities;

import java.awt.Color;

import eu.irreality.dai.gameplay.world.GameWorld;
import eu.irreality.dai.gameplay.world.LevelDescriptor;
import eu.irreality.dai.util.Position;
import eu.irreality.dai.world.level.Level;

public class Stairs extends Entity
{

    private static char UPSTAIRS_CHAR = '<';
    private static char DOWNSTAIRS_CHAR = '>';

    private char c;
    private boolean up;

    private Color color = Color.RED;

    private LevelDescriptor sourceDesc;
    private LevelDescriptor destinationDesc;

    private Position destinationPos;

    public LevelDescriptor getDestinationDescriptor()
    {
	return destinationDesc;
    }

    /**
     * Obtain the dungeon level to which the stairs lead.
     * 
     * @return
     */
    public Level getDestinationLevel()
    {
	return destinationDesc.getLevel();
    }

    /**
     * Obtain the (row,col) position in the destination level to which the
     * stairs lead.
     * 
     * @return
     */
    public Position getDestinationPosition()
    {
	if (!isDestinationPositionAssigned())
	    createTwoWayConnection();
	return destinationPos;
    }

    public void setDestinationPosition(Position p)
    {
	this.destinationPos = p;
    }

    /**
     * Tells us whether the destination (row,col) position has been assigned.
     * 
     * @return
     */
    public boolean isDestinationPositionAssigned()
    {
	return destinationPos != null;
    }

    public Stairs(boolean up, LevelDescriptor source,
	    LevelDescriptor destination)
    {
	this.up = up;
	if (up)
	    c = UPSTAIRS_CHAR;
	else
	    c = DOWNSTAIRS_CHAR;
	this.sourceDesc = source;
	this.destinationDesc = destination;
    }

    public boolean isUp()
    {
	return up;
    }

    @Override
    public char getChar()
    {
	return c;
    }

    @Override
    public Color getColor()
    {
	return color;
    }

    @Override
    public int getDisplayPriority()
    {
	return 100;
    }

    public void update(PropertyEntry pe, GameWorld world)
    {
	;
    }

    /**
     * This method should be called when these stairs have not been assigned a
     * destination position, but we want to assign it now. The destination level
     * will be generated if necessary to do this.
     */
    private void createTwoWayConnection()
    {
	// System.out.println("creatan connection");
	Level l = getDestinationLevel(); // note that this may generate the
	// destination level
	for (Entity e2 : l.getEntities())
	{
	    // System.out.println("Entity: " + e2);
	    if (e2 instanceof Stairs)
	    {
		Stairs s2 = (Stairs) e2;
		// System.out.println("A " + s2.isUp() + " stairs to " +
		// s2.getDestinationDescriptor() + " ( compare to " + sourceDesc
		// + ")");
		if (s2.isUp() != this.isUp()
			&& s2.getDestinationDescriptor() == sourceDesc)
		// note that we do not compare levels but descriptors here
		// comparing levels would lead to eager generation of the whole
		// graph
		{
		    // System.out.println("settan");
		    this.setDestinationPosition(s2.getPosition());
		    s2.setDestinationPosition(this.getPosition());
		}

	    }
	}
    }

}
